<?php
/*
 * description：
 * author：wh
 * email：
 * createTime：{2025/2/10} {10:11} 
 */

namespace wanghua\general_utility_tools_php\alipay;


use Alipay\EasySDK\Kernel\Config;
use Alipay\EasySDK\Kernel\Factory;
use wanghua\general_utility_tools_php\alipay\transfer\AlipayTransfer;
use wanghua\general_utility_tools_php\alipay\transfer\TransferConfig;
use wanghua\general_utility_tools_php\tool\Tools;

/**
 * 基础通用功能
 * 
 * 说明：
 * 支付和转账都能使用的功能
 * 
 * Class BaseAlipay
 * @package wanghua\general_utility_tools_php\alipay
 */
class BaseAlipay
{
    protected array $alipayConfig = [];
    public function __construct($alipayConfig)
    {
        $this->alipayConfig = $alipayConfig;
    }

    /**
     * 查询支付宝账户余额
     */
    function queryBalance(){
        //$transferConfig = new TransferConfig();
        //$transferConfig->cert_path_alipayCertPublicKey_RSA2 = Tools::get_root_path().$alipayConfig['cert_path_alipayCertPublicKey_RSA2'];//'<-- 请填写您的支付宝公钥证书文件路径，例如：/foo/alipayCertPublicKey_RSA2.crt -->';
        //$transferConfig->cert_path_alipayRootCert = Tools::get_root_path().$alipayConfig['cert_path_alipayRootCert'];//'<-- 请填写您的支付宝根证书文件路径，例如：/foo/alipayRootCert.crt" -->';
        //$transferConfig->appCertPublicKey = Tools::get_root_path().$alipayConfig['appCertPublicKey'];//'<-- 请填写您的应用公钥证书文件路径，例如：/foo/appCertPublicKey_2019051064521003.crt -->'

        //$trans_obj = new AlipayTransfer();
        Factory::setOptions($this->getAlipayOptions());

        $method = 'alipay.fund.account.query';
        //公共参数
        $textParams = [
            'app_id'=>$this->alipayConfig['app_id'],
            'charset'=>'utf-8',
            'sign_type'=>'RSA2',
            'timestamp'=>Tools::get_now_date(),
            'version'=>'1.0',
        ];

        //请求参数
        //订单号前缀
        $biz_content = [
            'account_type'=>'ACCTRANS_ACCOUNT',
        ];
        $pay_res = Factory::util()->generic()->execute($method,$textParams,$biz_content);

        return $pay_res;
    }

    /**
     * desc：证书模式参数（非证书模式参数需单独获取）
     * author：wh
     * @param array $this->alipayConfig 支付宝转账配置（非支付配置）
     * @return Config
     */
    function getAlipayOptions($notifyUrl='')
    {
        $root_path = Tools::get_root_path();
        $options = new Config();
        $options->protocol = 'https';
        $options->gatewayHost = 'openapi.alipay.com';
        $options->signType = 'RSA2';

        //'<-- 请填写您的AppId，例如：2019022663440152 -->'
        $options->appId = $this->alipayConfig['app_id'];//'2021002103639985';

        // 为避免私钥随源码泄露，推荐从文件中读取私钥字符串而不是写入源码中
        $options->merchantPrivateKey = $this->alipayConfig['alipay_app_private_key'];//'<-- 请填写您的应用私钥，例如：MIIEvQIBADANB ... ... -->';

        $options->alipayCertPath = $root_path.$this->alipayConfig['cert_path_alipayCertPublicKey_RSA2'];//'<-- 请填写您的支付宝公钥证书文件路径，例如：/foo/alipayCertPublicKey_RSA2.crt -->';
        $options->alipayRootCertPath = $root_path.$this->alipayConfig['cert_path_alipayRootCert'];//'<-- 请填写您的支付宝根证书文件路径，例如：/foo/alipayRootCert.crt" -->';
        $options->merchantCertPath = $root_path.$this->alipayConfig['appCertPublicKey'];//'<-- 请填写您的应用公钥证书文件路径，例如：/foo/appCertPublicKey_2019051064521003.crt -->';

        //注：如果采用非证书模式，则无需赋值上面的三个证书路径，改为赋值如下的支付宝公钥字符串即可
        // $options->alipayPublicKey = $this->alipayConfig['alipay_public_key'];//'<-- 请填写您的支付宝公钥，例如：MIIBIjANBg... -->';

        //可设置异步通知接收服务地址（可选）
        $options->notifyUrl = $notifyUrl;//"<-- 请填写您的支付类接口异步通知接收服务地址，例如：https://www.test.com/callback -->";

        //可设置AES密钥，调用AES加解密相关接口时需要（可选）
        //$options->encryptKey = "<-- 请填写您的AES密钥，例如：aa4BtZ4tspm2wnXLb1ThQA== -->";

        return $options;
    }

    /**
     * 支付宝退款
     *
     * 注意：需要在正式服测，本地会报错
     *
     * doc:
     * https://opendocs.alipay.com/open/3aea9b48_alipay.trade.refund?pathHash=4de421df&scene=common
     *
     * 测试结果:
     * object(Alipay\EasySDK\Util\Generic\Models\AlipayOpenApiGenericResponse)#93 (7) {
    ["_name":protected] =&gt; array(5) {
    ["httpBody"] =&gt; string(9) "http_body"
    ["code"] =&gt; string(4) "code"
    ["msg"] =&gt; string(3) "msg"
    ["subCode"] =&gt; string(8) "sub_code"
    ["subMsg"] =&gt; string(7) "sub_msg"
    }
    ["httpBody"] =&gt; string(826) "{"alipay_trade_refund_response":{"code":"10000","msg":"Success","buyer_logon_id":"150******25","fund_change":"Y","gmt_refund_pay":"2025-02-24 10:06:26","out_trade_no":"h5cqa31h1740360008389","refund_detail_item_list":[{"amount":"0.11","fund_channel":"ALIPAYACCOUNT"}],"refund_fee":"0.11","send_back_fee":"0.11","trade_no":"2025022422001457441416271979","buyer_open_id":"0442qO88pZKcduCIdYq7Z4N8y29dGoocWheNow1jt_QW1k4"},"alipay_cert_sn":"9cbb86296783f52af85119eb59308f9a","sign":"fcmu9CwYw0uziZTNImfGJvaYE9EdO4OoeKjktl/jxn+EGKvybDijKxTsn+jRM99jm9gcvmQmqweTd6OJMkep6cut1Tl5jsktYGy+ri1lLTGc9eNg+ctyO6qylnVaKQstV0QNZkuRo6Y36W3ZXolZk81ppNM1chtupsALHfwoWSirupqJ6Y52iBRG67kN0AxexL8mbOhwGS9vAMbMXoyRKJ7ajLGSmpnhb1sMvHVhFkvXaCBrzn6Nt1TMw6cyelqNHsAsmJ+OSnndVcRaqt9Q+IAwn98vhBhl1J5Vi7cWbsIYeki+TViQZ2ArW09IdBrP+A9qIydeM0BQdElRFWntvg=="}"
    ["code"] =&gt; string(5) "10000"
    ["msg"] =&gt; string(7) "Success"
    ["subCode"] =&gt; NULL
    ["subMsg"] =&gt; NULL
    ["_required":protected] =&gt; array(0) {
    }
    }
     */
    function aliRefund($order_info){
        $alipayConfig = $this->alipayConfig;
        //$transferConfig = new TransferConfig();
        //$transferConfig->cert_path_alipayCertPublicKey_RSA2 = Tools::get_root_path().$alipayConfig['cert_path_alipayCertPublicKey_RSA2'];//'<-- 请填写您的支付宝公钥证书文件路径，例如：/foo/alipayCertPublicKey_RSA2.crt -->';
        //$transferConfig->cert_path_alipayRootCert = Tools::get_root_path().$alipayConfig['cert_path_alipayRootCert'];//'<-- 请填写您的支付宝根证书文件路径，例如：/foo/alipayRootCert.crt" -->';
        //$transferConfig->appCertPublicKey = Tools::get_root_path().$alipayConfig['appCertPublicKey'];//'<-- 请填写您的应用公钥证书文件路径，例如：/foo/appCertPublicKey_2019051064521003.crt -->'


        Factory::setOptions($this->getAlipayOptions());

        $method = 'alipay.trade.refund';
        //公共参数
        $textParams = [
            'app_id'=>$alipayConfig['app_id'],
            'charset'=>'utf-8',
            'sign_type'=>'RSA2',
            'timestamp'=>Tools::get_now_date(),
            'version'=>'1.0',
        ];

        //请求参数 wap/pc/app支付

        //【描述】退分账明细信息。
        // 注： 1.当面付且非直付通模式无需传入退分账明细，系统自动按退款金额与订单金额的比率，
        //从收款方和分账收入方退款，不支持指定退款金额与退款方。
        // 2.直付通模式，电脑网站支付，手机 APP 支付，手机网站支付产品，须在退款请求中明确是否退分账，
        //从哪个分账收入方退，退多少分账金额；
        //如不明确，默认从收款方退款，收款方余额不足退款失败。不支持系统按比率退款。
        $refund_royalty_parameters = [];//如果有分账，此项必填
        //订单号前缀
        $biz_content = [
            //'account_type'=>'ACCTRANS_ACCOUNT',
            'out_trade_no'=>$order_info['orderid'],
            'refund_amount'=>$order_info['real_amount'],
        ];
        if($refund_royalty_parameters){
            $biz_content['refund_royalty_parameters'] = $refund_royalty_parameters;
        }
        $pay_res = Factory::util()->generic()->execute($method,$textParams,$biz_content);

        return $pay_res;

    }
}